using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using SecuBat.AttackPlugin;
using SecuBat.Modularization.Plugins;
using Css.Diagnostics;

namespace SecuBat.UI
{
	/// <summary>
	/// Summary description for Plugins.
	/// </summary>
	public class PluginsForm : System.Windows.Forms.Form
	{
        private System.Windows.Forms.OpenFileDialog openFileDialogPlugin;
		private System.Windows.Forms.Label labelPlugins;
		private Button ultraButtonAddPlugin;
		private Button ultraButtonOK;
		private Button ultraButtonCancel;
        private PluginCollection _plugins;
        private DataGridView dataGridViewPlugins;
        private DataGridViewTextBoxColumn colId;
        private DataGridViewTextBoxColumn colFilename;
        private DataGridViewTextBoxColumn colName;
        private DataGridViewTextBoxColumn colDesc;
        private DataGridViewTextBoxColumn colVersion;
        private DataGridViewTextBoxColumn colState;
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

		public PluginsForm(PluginCollection plugins)
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
			_plugins = plugins;
			RefreshDatasource();
            string pluginDir = Path.GetDirectoryName(
                Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);
			openFileDialogPlugin.InitialDirectory = pluginDir;
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.openFileDialogPlugin = new System.Windows.Forms.OpenFileDialog();
            this.labelPlugins = new System.Windows.Forms.Label();
            this.ultraButtonAddPlugin = new System.Windows.Forms.Button();
            this.ultraButtonOK = new System.Windows.Forms.Button();
            this.ultraButtonCancel = new System.Windows.Forms.Button();
            this.dataGridViewPlugins = new System.Windows.Forms.DataGridView();
            this.colId = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.colFilename = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.colName = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.colDesc = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.colVersion = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.colState = new System.Windows.Forms.DataGridViewTextBoxColumn();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridViewPlugins)).BeginInit();
            this.SuspendLayout();
            // 
            // openFileDialogPlugin
            // 
            this.openFileDialogPlugin.Filter = "Plugins|*.dll";
            // 
            // labelPlugins
            // 
            this.labelPlugins.Location = new System.Drawing.Point(8, 8);
            this.labelPlugins.Name = "labelPlugins";
            this.labelPlugins.Size = new System.Drawing.Size(100, 23);
            this.labelPlugins.TabIndex = 2;
            this.labelPlugins.Text = "Plugins:";
            this.labelPlugins.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            // 
            // ultraButtonAddPlugin
            // 
            this.ultraButtonAddPlugin.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.ultraButtonAddPlugin.Location = new System.Drawing.Point(8, 232);
            this.ultraButtonAddPlugin.Name = "ultraButtonAddPlugin";
            this.ultraButtonAddPlugin.Size = new System.Drawing.Size(104, 23);
            this.ultraButtonAddPlugin.TabIndex = 3;
            this.ultraButtonAddPlugin.Text = "&Add Plugin...";
            this.ultraButtonAddPlugin.Click += new System.EventHandler(this.ultraButtonAddPlugin_Click);
            // 
            // ultraButtonOK
            // 
            this.ultraButtonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.ultraButtonOK.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.ultraButtonOK.Location = new System.Drawing.Point(504, 232);
            this.ultraButtonOK.Name = "ultraButtonOK";
            this.ultraButtonOK.Size = new System.Drawing.Size(104, 23);
            this.ultraButtonOK.TabIndex = 4;
            this.ultraButtonOK.Text = "&OK";
            // 
            // ultraButtonCancel
            // 
            this.ultraButtonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.ultraButtonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.ultraButtonCancel.Location = new System.Drawing.Point(624, 232);
            this.ultraButtonCancel.Name = "ultraButtonCancel";
            this.ultraButtonCancel.Size = new System.Drawing.Size(104, 23);
            this.ultraButtonCancel.TabIndex = 5;
            this.ultraButtonCancel.Text = "&Cancel";
            // 
            // dataGridViewPlugins
            // 
            this.dataGridViewPlugins.AllowUserToAddRows = false;
            this.dataGridViewPlugins.AllowUserToDeleteRows = false;
            this.dataGridViewPlugins.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
            this.dataGridViewPlugins.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridViewPlugins.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.colId,
            this.colFilename,
            this.colName,
            this.colDesc,
            this.colVersion,
            this.colState});
            this.dataGridViewPlugins.Location = new System.Drawing.Point(8, 34);
            this.dataGridViewPlugins.Name = "dataGridViewPlugins";
            this.dataGridViewPlugins.ReadOnly = true;
            this.dataGridViewPlugins.RowHeadersVisible = false;
            this.dataGridViewPlugins.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
            this.dataGridViewPlugins.Size = new System.Drawing.Size(720, 190);
            this.dataGridViewPlugins.TabIndex = 6;
            // 
            // colId
            // 
            this.colId.HeaderText = "ID";
            this.colId.Name = "colId";
            this.colId.ReadOnly = true;
            this.colId.Visible = false;
            // 
            // colFilename
            // 
            this.colFilename.HeaderText = "Filename";
            this.colFilename.Name = "colFilename";
            this.colFilename.ReadOnly = true;
            this.colFilename.Visible = false;
            // 
            // colName
            // 
            this.colName.FillWeight = 20F;
            this.colName.HeaderText = "Name";
            this.colName.Name = "colName";
            this.colName.ReadOnly = true;
            // 
            // colDesc
            // 
            this.colDesc.FillWeight = 50F;
            this.colDesc.HeaderText = "Description";
            this.colDesc.Name = "colDesc";
            this.colDesc.ReadOnly = true;
            // 
            // colVersion
            // 
            this.colVersion.FillWeight = 15F;
            this.colVersion.HeaderText = "Version";
            this.colVersion.Name = "colVersion";
            this.colVersion.ReadOnly = true;
            // 
            // colState
            // 
            this.colState.FillWeight = 15F;
            this.colState.HeaderText = "State";
            this.colState.Name = "colState";
            this.colState.ReadOnly = true;
            // 
            // PluginsForm
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(736, 266);
            this.Controls.Add(this.dataGridViewPlugins);
            this.Controls.Add(this.ultraButtonCancel);
            this.Controls.Add(this.ultraButtonOK);
            this.Controls.Add(this.ultraButtonAddPlugin);
            this.Controls.Add(this.labelPlugins);
            this.MinimumSize = new System.Drawing.Size(400, 200);
            this.Name = "PluginsForm";
            this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
            this.Text = "Plugins";
            this.Resize += new System.EventHandler(this.PluginsForm_Resize);
            ((System.ComponentModel.ISupportInitialize)(this.dataGridViewPlugins)).EndInit();
            this.ResumeLayout(false);

		}
		#endregion

		private void PluginsForm_Resize(object sender, System.EventArgs e)
		{
			dataGridViewPlugins.Width = this.Width - 24;
            dataGridViewPlugins.Height = this.Height - 108;


		}

		private void ultraButtonAddPlugin_Click(object sender, System.EventArgs e)
		{
			DialogResult result = openFileDialogPlugin.ShowDialog(this);
			if (result.Equals(DialogResult.OK))
			{
				String filename = openFileDialogPlugin.FileName;
				if (File.Exists(filename))
				{
					Plugin p = new Plugin(filename);
					if (p.State == PluginState.Loaded)
					{
                        // Check for duplicates
                        bool duplicate = false;
                        foreach (Plugin plug in _plugins.Values)
                        {
                            if (p.Filename.ToLower() == plug.Filename.ToLower() &&
                                p.Version == plug.Version)
                                duplicate = true;
                        }

                        if (!duplicate)
                        {
                            if (p.Register())
                            {
                                _plugins.Add(p);
                                RefreshDatasource();
                            }
                            else
                                MessageBox.Show(this, "The plugin failed to register into database!", "Plugin failure", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                        else
                            MessageBox.Show(this, "A plugin with this filename and version is already registered!", "Plugin failure", MessageBoxButtons.OK, MessageBoxIcon.Error);
					}
					else
					{
						switch (p.State)
						{
							case PluginState.GeneralError:
								MessageBox.Show(this, "A general error occured while loading the plugin!", "Plugin failure", MessageBoxButtons.OK, MessageBoxIcon.Error);
								break;
							case PluginState.Incompatible:
								MessageBox.Show(this, "The selected file was not a compatible plugin!", "Plugin failure", MessageBoxButtons.OK, MessageBoxIcon.Error);
								break;
							case PluginState.NoAttackNoAnalysis:
								MessageBox.Show(this, "The selected plugin did not contain a valid attack class nor an analysis class!", "Plugin failure", MessageBoxButtons.OK, MessageBoxIcon.Error);
								break;
							case PluginState.NoAnalysis:
								MessageBox.Show(this, "The selected plugin did not contain a valid analysis class!", "Plugin failure", MessageBoxButtons.OK, MessageBoxIcon.Error);
								break;
							case PluginState.NoAttack:
								MessageBox.Show(this, "The selected plugin did not contain a valid attack class!", "Plugin failure", MessageBoxButtons.OK, MessageBoxIcon.Error);
								break;
							case PluginState.WrongInterfaces:
								MessageBox.Show(this, "The attack or analysis classes in the selected plugin do not implement the needed interfaces!", "Plugin failure", MessageBoxButtons.OK, MessageBoxIcon.Error);
								break;
							case PluginState.NotFound:
								MessageBox.Show(this, "The selected file was not found!", "Plugin failure", MessageBoxButtons.OK, MessageBoxIcon.Error);
								break;
						}
					}
				}
			}
		
		}

		private void RefreshDatasource()
		{
			this.dataGridViewPlugins.Rows.Clear();
			foreach (Plugin p in _plugins.Values)
			{
                this.dataGridViewPlugins.Rows.Add(new object[] { p.Id, p.Filename, p.Name, p.Description, p.Version, p.State.ToString() });
			}
		}
	}
}
